package cn.zhangfusheng.elasticsearch.repository;

import cn.zhangfusheng.elasticsearch.exception.GlobalSystemException;
import cn.zhangfusheng.elasticsearch.scan.ElasticSearchEntityRepositoryDetail;
import org.elasticsearch.common.xcontent.XContentBuilder;

import java.util.Optional;

/**
 * @author fusheng.zhang
 * @date 2022-03-01 11:01:46
 */
public interface DefaultElasticSearchEditRepository<T> extends DefaultRepository<T> {

    @Override
    default boolean insert(T t) {
        ElasticSearchEntityRepositoryDetail entityRepositoryDetail = entityRepositoryDetail();
        String id = entityRepositoryDetail.primaryIdIfNullSet(t);
        String routing = entityRepositoryDetail.routing(t);
        entityRepositoryDetail.setCreateTime(t).setUpdateTime(t);
        String indexName = entityRepositoryDetail.getSearchIndex();
        XContentBuilder xContentBuilder = entityRepositoryDetail.entityToXContentBuilder(t, Boolean.FALSE);
        return elasticSearchRestTemplate().index(id, routing, indexName, xContentBuilder);
    }

    @Override
    default boolean updateById(T t, boolean excludeNull) {
        ElasticSearchEntityRepositoryDetail entityRepositoryDetail = entityRepositoryDetail();
        Optional<String> idOption = entityRepositoryDetail.primaryId(t);
        String id = idOption.orElseThrow(() ->
                new GlobalSystemException("primaryId {} is null", entityRepositoryDetail.getPrimaryId().getName()));
        String indexName = entityRepositoryDetail.getSearchIndex();
        String routing = entityRepositoryDetail.routing(t);
        entityRepositoryDetail.setUpdateTime(t);
        XContentBuilder xContentBuilder = entityRepositoryDetail.entityToXContentBuilder(t, excludeNull);
        return elasticSearchRestTemplate().update(indexName, routing, id, xContentBuilder);
    }

    @Override
    default boolean deleteById(String primaryId) {
        return this.deleteById(primaryId, null);
    }

    @Override
    default boolean deleteById(String primaryId, String routing) {
        String indexName = entityRepositoryDetail().getSearchIndex();
        return elasticSearchRestTemplate().delete(indexName, routing, primaryId);
    }
}
